Since a few weeks I own an HP Pavilion Aero 13 which I want to use as travel laptop. This little thing has less than a kilogram and is powered by a beefy AMD Ryzen 5 5600U. Unfortunately, S3 suspend does not work on linux. It’s not because the device does not support it. It is because some stupid HP engineers decided not to expose this feature to the operating system.
Fortunately, linux allows to patch the ACPI table at boot, unveiling otherwise unavailable features to the operating system. After an hour of reserach, I found the required pieces in a reply at https://bbs.archlinux.org/viewtopic.php?pid=1975083#p1975083. In this post I document everything needed to activate S3 on linux on this device.
To see whether s3 is available, check the output of dmesg:
#> sudo dmesg | grep - "ACPI: PM: (supports" [ 0.376849] ACPI: PM: (supports S0 S4 S5)
If S3 is missing, suspend is only possible with „s2idle“, not with the better „deep“ sleep mode:
#> cat /sys/power/mem_sleep [s2idle]
To get this fixed, the ACPI table needs to be dumped, modified and compiled. The compiled table can then be loaded by the kernel.
Install acpica and cpio. On archlinux it is done with the following command (on debien, the package is acpica-tools):
sudo pacman -S acpica cpio
Now the ACPI table can be dumped and decompiled into a folder:
mkdir /tmp/acpi cd /tmp/acpi acpidump -b iasl -e *.dat -d dsdt.dat iasl -d facp.dat
This creates a lot of files. The last 2 steps creates dsdt.dsl and facp.dsl which are readable versions of the tables.
In facp.dsl, only the „Oem Revision“ must be increased. I changed it from 01072009 to 01072010. Here is a patch:
#> diff -u facp.dsl.orig facp.dsl --- facp.dsl.org 2023-01-21 19:18:29.977306514 +0100 +++ facp.dsl 2023-01-21 19:18:32.090610166 +0100 @@ -16,7 +16,7 @@ [009h 0009 001h] Checksum : 50 [00Ah 0010 006h] Oem ID : "HPQOEM" [010h 0016 008h] Oem Table ID : "SLIC-MPC" -[018h 0024 004h] Oem Revision : 01072009 +[018h 0024 004h] Oem Revision : 01072010 [01Ch 0028 004h] Asl Compiler ID : "HP " [020h 0032 004h] Asl Compiler Revision : 00010013
In dsdt.dsl, I also changed this revision to 01072010. Then I added the missing definition block for the S3 sleep mode. Way below, around line 9250 is a dupplicate block in a switch statement that fails during compilation. I just removed it. Here is the patch for this file:
#> diff -u dsdt.dsl.orig dsdt.dsl --- dsdt.dsl.orig 2023-01-21 19:13:51.847853395 +0100 +++ dsdt.dsl 2023-01-21 19:23:15.456611450 +0100 @@ -18,7 +18,7 @@ * Compiler ID "ACPI" * Compiler Version 0x20190509 (538510601) */ -DefinitionBlock ("", "DSDT", 2, "HPQOEM", "8916 ", 0x01072009) +DefinitionBlock ("", "DSDT", 2, "HPQOEM", "8916 ", 0x01072010) { External (_GPE, DeviceObj) External (_PR_.P000, UnknownObj) @@ -3016,6 +3016,13 @@ Zero, Zero }) + Name (_S3, Package (0x04) + { + 0x03, + 0x03, + Zero, + Zero + }) Name (_S4, Package (0x04) // _S4_: S4 System State { 0x04, @@ -9221,24 +9228,6 @@ } Case (0x03) { - DerefOf (Local0 [0x02]) [One] = Zero - DerefOf (Local0 [0x02]) [0x02] = Zero - DerefOf (Local0 [0x02]) [0x03] = Zero - DerefOf (Local0 [0x02]) [0x04] = Zero - DerefOf (Local0 [0x02]) [0x05] = Zero - DerefOf (Local0 [0x02]) [0x06] = Zero - DerefOf (Local0 [0x02]) [0x07] = Zero - DerefOf (Local0 [0x02]) [0x08] = Zero - DerefOf (Local0 [0x02]) [0x09] = Zero - DerefOf (Local0 [0x02]) [0x0A] = Zero - DerefOf (Local0 [0x02]) [0x0B] = Zero - DerefOf (Local0 [0x02]) [0x0C] = Zero - DerefOf (Local0 [0x02]) [0x0D] = Zero - DerefOf (Local0 [0x02]) [0x0E] = Zero - DerefOf (Local0 [0x02]) [0x0F] = Zero - } - Case (0x03) - { DerefOf (Local0 [0x02]) [One] = Zero DerefOf (Local0 [0x02]) [0x02] = Zero DerefOf (Local0 [0x02]) [0x03] = Zero
Now, both files can be compiled:
#> iasl -ve -tc dsdt.dsl #> iasl -ve -tc facp.dsl
The result are dsdt.aml and facp.dsl. These files must be packet and can then be used as a initrd.
#> mkdir -p kernel/firmware/acpi #> cp *.aml kernel/firmware/acpi #> find kernel | cpio -H newc --create > acpi_override.cpio.img #> sudo cp acpi_override.cpio.img /boot/
Now the initrd needs to be added to grub config. Ihis can be done by adding a line to /etc/default/grub. Also and option should be added to the linux command line that enforces to use deep sleep as default.
GRUB_EARLY_INITRD_LINUX_CUSTOM="acpi_override.cpio.img" GRUB_CMDLINE_LINUX="... mem_sleep_default=deep"
Re-create the grub config:
sudo sh -c "grub-mkconfig > /boot/grub/grub.cfg"
After a reboot, S3 and suspend-to ram should be available and enabled:
#> sudo dmesg | grep - "ACPI: PM: (supports" [ 0.376849] ACPI: PM: (supports S0 S3 S4 S5) #> cat /sys/power/mem_sleep s2idle [deep]
Thanks for the clear instructions, I managed to get S3 working on my Aero 13 as well! This solves my biggest gripe with the machine, apart from its abysmal battery life. I somewhat mitigated that by using the ‚conservative‘ CPU scaling governor. But if you have any suggestions to improve power use, I would greatly appreciate that.
Hello,
I’m running alpine on it with no special settings and battery is good enough for my use (I use it only for couch-surfing and abroad). A bit annoying is that the battery life is always reported way shorter that it actually is. I think the consumption reporting is broken – but it’s also on windows, so it seems to be another ACPI issue.